# -*- coding: utf-8 -*-
"""img2pdf_mixin
图片批量转 PDF 线程功能模块。
将 main.py 中 def convert_images_to_pdf_thread(...) 剪切粘贴到 class Img2PdfMixin 内。
"""

import os
import traceback
from tkinter import messagebox
import fitz  # PyMuPDF
from PIL import Image, ImageOps


class Img2PdfMixin:
    """图片 ➜ PDF 相关方法 mixin"""
    def convert_images_to_pdf_thread(self):
        """将图片转换为PDF的线程 (根据选择的模式和尺寸选项)"""
        try:
            total_images = len(self.image_paths)
            sizing_mode = self.img_sizing_mode.get() if self.conversion_mode.get() == "single" else None
            conversion_mode = self.conversion_mode.get()

            # A4尺寸 @ 72 DPI (PDF standard points)
            A4_WIDTH_PT, A4_HEIGHT_PT = 595.276, 841.890

            skipped_files = []

            if conversion_mode == "single":
                # --- 合并为单个PDF ---
                self.after(0, self.img_status_label.configure, {"text": "准备合并处理图片..."})

                pdf_doc = fitz.open()  # Final output PDF
                first_image_target_dimensions_rect = None  # For "match_first" sizing mode

                for idx, img_path in enumerate(self.image_paths):
                    status_text = f"处理图片: {idx + 1}/{total_images} ({os.path.basename(img_path)})"
                    progress = (idx + 1) / total_images
                    self.after(0, self.update_progress_safe, progress, status_text)

                    img_source_doc = None  # To open the original image file
                    img_one_page_pdf = None  # To hold the image converted to a 1-page PDF

                    try:
                        # --- Stage 1: Convert current image to a temporary one-page PDF ---
                        img_source_doc = fitz.open(img_path)
                        if not img_source_doc or img_source_doc.page_count == 0:
                            raise Exception(f"无法打开图片文件或图片文件没有内容: {os.path.basename(img_path)}")

                        # Core change: use convert_to_pdf() for image-to-PDF representation
                        img_as_pdf_bytes = img_source_doc.convert_to_pdf()
                        if not img_as_pdf_bytes:
                            raise Exception(f"convert_to_pdf() 未能转换图片: {os.path.basename(img_path)}")

                        img_one_page_pdf = fitz.open("pdf", img_as_pdf_bytes)
                        if not img_one_page_pdf or img_one_page_pdf.page_count == 0:
                            raise Exception(f"从图片字节流创建临时PDF失败: {os.path.basename(img_path)}")

                        img_intrinsic_rect = img_one_page_pdf[0].rect # Image's natural dimensions as a PDF page

                        # --- Stage 2: Determine target page dimensions in the main output PDF ---
                        current_target_page_rect_for_main_doc = None
                        if sizing_mode == "original":
                            current_target_page_rect_for_main_doc = img_intrinsic_rect
                        elif sizing_mode == "a4":
                            current_target_page_rect_for_main_doc = fitz.Rect(0, 0, A4_WIDTH_PT, A4_HEIGHT_PT)
                        elif sizing_mode == "match_first":
                            if idx == 0:
                                first_image_target_dimensions_rect = img_intrinsic_rect
                                current_target_page_rect_for_main_doc = img_intrinsic_rect
                            else:
                                if first_image_target_dimensions_rect is None:
                                    # This case should ideally be prevented by successful processing of the first image.
                                    # If first image failed, subsequent "match_first" will also fail here.
                                    raise Exception("第一张图片未能确定尺寸，无法匹配。")
                                current_target_page_rect_for_main_doc = first_image_target_dimensions_rect
                        else:  # Default to original if somehow sizing_mode is unrecognized
                            current_target_page_rect_for_main_doc = img_intrinsic_rect
                        
                        if current_target_page_rect_for_main_doc is None or current_target_page_rect_for_main_doc.is_empty:
                            raise Exception(f"未能确定目标页面尺寸: {os.path.basename(img_path)}")

                        # --- Stage 3: Create page in main PDF and draw the image (from its PDF form) onto it ---
                        page_in_main_doc = pdf_doc.new_page(
                            width=current_target_page_rect_for_main_doc.width,
                            height=current_target_page_rect_for_main_doc.height
                        )

                        # Define source (image's own PDF page) and canvas (page in main_doc)
                        src_rect_to_draw_from = img_intrinsic_rect # The content area of the image's temp PDF
                        canvas_rect_to_draw_on = page_in_main_doc.rect # The full new page in the output PDF

                        if canvas_rect_to_draw_on.is_empty or src_rect_to_draw_from.is_empty:
                            print(f"警告：图片 {os.path.basename(img_path)} 的源或目标矩形为空，跳过绘制。")
                            continue

                        # Calculate position and size to draw the image, maintaining aspect ratio and centering
                        img_w = src_rect_to_draw_from.width
                        img_h = src_rect_to_draw_from.height
                        page_w = canvas_rect_to_draw_on.width
                        page_h = canvas_rect_to_draw_on.height

                        if img_w <= 0 or img_h <= 0:
                            print(f"警告：图片 {os.path.basename(img_path)} 的固有尺寸无效 ({img_w}x{img_h})，跳过。")
                            continue
                        
                        # Aspect ratio scaling and centering logic
                        img_aspect = img_w / img_h
                        page_aspect = page_w / page_h
                        
                        scaled_w, scaled_h = 0, 0
                        if img_aspect > page_aspect: # Image is wider than canvas (relative to height) -> fit by width
                            scaled_w = page_w
                            scaled_h = scaled_w / img_aspect
                        else: # Image is taller than canvas (relative to width) or same aspect -> fit by height
                            scaled_h = page_h
                            scaled_w = scaled_h * img_aspect
                        
                        pos_x = (page_w - scaled_w) / 2
                        pos_y = (page_h - scaled_h) / 2
                        
                        # This is the rectangle on page_in_main_doc where img_one_page_pdf[0]'s content will be shown
                        draw_rect_on_page = fitz.Rect(pos_x, pos_y, pos_x + scaled_w, pos_y + scaled_h)
                        
                        page_in_main_doc.show_pdf_page(draw_rect_on_page, img_one_page_pdf, 0) # Draw page 0 of img_one_page_pdf

                    except Exception as e:
                        error_msg = f"处理图片 {os.path.basename(img_path)} 时出错: {e}"
                        print(error_msg)
                        # Optionally, include more details from traceback for debugging if needed
                        # print(traceback.format_exc())
                        skipped_files.append(f"{os.path.basename(img_path)} (错误: {str(e)})")
                        self.after(0, self.update_progress_safe, progress, status_text + " - 错误")
                        continue # Skip to the next image
                    finally:
                        # Ensure temporary documents for the current image are closed
                        if img_one_page_pdf:
                            try:
                                img_one_page_pdf.close()
                            except Exception as e_close:
                                print(f"关闭临时图片PDF时出错 {os.path.basename(img_path)}: {e_close}")
                        if img_source_doc:
                            try:
                                img_source_doc.close()
                            except Exception as e_close:
                                print(f"关闭源图片文件时出错 {os.path.basename(img_path)}: {e_close}")
                
                # After loop, save the main document
                if len(pdf_doc) > 0:
                    pdf_doc.save(self.output_path, garbage=4, deflate=True)
                else:
                    # Only show error if no files were skipped (means first file failed?)
                    if not skipped_files:
                        raise Exception("No images could be processed.")
                    else:
                        print("No pages added to PDF as all initial images failed or were skipped.")

                pdf_doc.close()

            else:
                # --- 批量转换模式 (每张图片一个PDF) ---
                if not os.path.isdir(self.output_path):
                    # This check should be done in start method, but double check
                    raise ValueError("Output path must be a valid folder for batch mode.")

                for idx, img_path in enumerate(self.image_paths):
                    img_name = os.path.splitext(os.path.basename(img_path))[0]
                    safe_img_name = "".join(
                        c if c.isalnum() or c in (' ', '_', '-') else '_' for c in img_name).rstrip()
                    if not safe_img_name: safe_img_name = f"image_{idx + 1}"
                    output_file = os.path.join(self.output_path, f"{safe_img_name}.pdf")

                    status_text = f"处理图片: {idx + 1}/{total_images} -> {safe_img_name}.pdf"
                    progress = (idx + 1) / total_images
                    self.after(0, self.update_progress_safe, progress, status_text)

                    try:
                        # Use fitz utility function for simple conversion
                        img_doc = fitz.open(img_path)
                        pdf_bytes = img_doc.convert_to_pdf()  # Simple conversion
                        img_doc.close()

                        pdf_doc_out = fitz.open("pdf", pdf_bytes)  # Load the converted bytes
                        pdf_doc_out.save(output_file, garbage=4, deflate=True)
                        pdf_doc_out.close()

                        # Alternative: Manual PIL method (more control but maybe slower)
                        # img = Image.open(img_path)
                        # img = ImageOps.exif_transpose(img)
                        # if img.mode != 'RGB':
                        #     img = img.convert('RGB')
                        # img.save(output_file, "PDF", resolution=100.0)
                        # img.close()

                    except Exception as e:
                        print(f"Error converting image {img_path} to PDF: {e}")
                        skipped_files.append(os.path.basename(img_path))
                        continue  # Skip this file

            # --- 完成处理 ---
            final_status = "转换完成"
            self.after(0, self.update_progress_safe, 1.0, final_status)

            # Show final message
            if skipped_files:
                skipped_list = "\n - ".join(skipped_files)
                warning_message = (f"转换完成！\n\n{total_images - len(skipped_files)} 个图片成功转换。\n"
                                   f"{len(skipped_files)} 个图片处理失败/跳过:\n - {skipped_list}\n\n"
                                   f"结果保存在: {self.output_path}")
                self.after(0, messagebox.showwarning, "部分完成", warning_message)
            else:
                success_message = (f"图片转PDF成功！\n\n已处理 {total_images} 个图片。\n"
                                   f"结果保存在: {self.output_path}")
                self.after(0, messagebox.showinfo, "完成", success_message)


        except ValueError as ve:
            self.after(0, messagebox.showerror, "输入错误", f"输入错误: {str(ve)}")
            self.after(0, self.update_progress_safe, 0, "转换失败")
        except Exception as e:
            error_details = traceback.format_exc()
            self.after(0, self.show_error_message, f"转换过程中出现错误：{str(e)}\n{error_details}")
            self.after(0, self.update_progress_safe, 0, "转换失败")

        finally:
            # 重置UI
            self.after(0, self.reset_ui_state, self.img_convert_btn, self.img_progress_bar, self.img_status_label,
                       "准备就绪")
